home *** CD-ROM | disk | FTP | other *** search
-
- /* This file holds the functions for manipulating video memory */
-
- #include <stdio.h>
- #include "video.h"
- #include "terminal.h"
-
- /* This function returns a pointer to a video memory area of ints.
- Integers are used to encode both the characters and the flags.
- If this function fails, it should be a fatal error. Allocated
- memory is not freed if the function fails.
- */
-
- int **alloc_video(rows, cols)
- int rows;
- int cols;
- {
- int **videomem;
- int i, j;
-
- /* Allocate row pointers */
- if ( (videomem=(int **)malloc(rows*sizeof(int *))) == NULL )
- return(NULL);
-
- /* Allocate the columns for each row */
- for ( i=0; i<rows; ++i ) {
- if ( (videomem[i]=(int *)malloc(cols*sizeof(int))) == NULL )
- return(NULL);
- for ( j=0; j<cols; ++j )
- videomem[i][j]=0;
- }
- return(videomem);
- }
-
- /* This function copies an existing window to a new buffer,
- truncating lines if necessary, and translates the cursor position */
- void copy_video(win, newarea, rows, cols, newcursor)
- window *win;
- int **newarea;
- int rows;
- int cols;
- position *newcursor;
- {
- int i, j, ni, nj;
-
- /* Copy from the bottom up... */
- newcursor->x=0;
- for ( i=win->rows, ni=rows; i && ni; --i, --ni ) {
- if ( win->cursor.x == i ) {
- if ( (newcursor->x=(i+rows-win->rows)) < 1 )
- newcursor->x=1;
- }
- for ( j=0, nj=0; (j<win->cols) && (nj<cols); ++j, ++nj )
- newarea[ni-1][nj]=win->videomem[i-1][j];
- }
- if ( ! newcursor->x ) /* We never reached the old cursor */
- newcursor->x=1;
- newcursor->y=(win->cursor.y > cols ? cols : win->cursor.y);
- }
-
- /* This function adds a character to the video memory at the cursor position */
- void add_video(win, c)
- window *win;
- char c;
- {
- win->videomem[win->cursor.x - 1][win->cursor.y - 1] = (int)c;
- win->videomem[win->cursor.x - 1][win->cursor.y - 1] |=
- (((int)win->textattr)<<8);
- }
-
- /* This function returns a character from video at a specific position */
- int get_video(win, x, y)
- window *win;
- int x, y;
- {
- return(win->videomem[x-1][y-1]);
- }
-
- /* This function sets a character position in video memory */
- void put_video(c, win, x, y)
- int c;
- window *win;
- int x, y;
- {
- win->videomem[x-1][y-1]=c;
- }
-
- /* This function returns the array index of the end of the specified line
- in the specified window. lineno should start as 1 for the first line.
- */
- static int video_eol(win, lineno)
- window *win;
- int lineno;
- {
- int eol=(-1), j;
-
- for ( j=0; j<win->cols; ++j ) {
- if ( (win->videomem[lineno-1][j]&0xFF) != 0 )
- eol=j;
- }
- ++eol;
- return(eol);
- }
-
- /* This function copies a specified section of video memory to a buffer */
- /* x1 is the first line, x2 is the second line, y1 is the y on the first
- line, and y2 is the y on the last line.
- */
- void getsel_video(win, buf, maxlen, x1, x2, y1, y2)
- window *win;
- char *buf;
- int maxlen;
- int x1, x2;
- int y1, y2;
- {
- int l=0, i, j, eol, eos;
-
- --maxlen; /* Account for trailing null */
- for ( i=(x1-1); (i<x2 && l<maxlen); ++i ) {
- eol=video_eol(win, i+1);
- if ( i == (x1-1) ) {
- j=(y1-1);
- eos=eol;
- } else
- j=0;
- if ( i == (x2-1) )
- eos=((y2-1) < eol ? (y2-1) : eol);
- for ( ; j<eos; ++j ) {
- if ( win->videomem[i][j] == 0 )
- *(buf++) = ' ';
- else
- *(buf++) = win->videomem[i][j];
- ++l;
- }
- if ( l<maxlen && j >= eol ) {
- *(buf++) = '\r';
- ++l;
- }
- }
- *buf='\0';
- return;
- }
-
- /* This function clears the SELECTED bit in a whole window */
- void clrsel_video(win)
- window *win;
- {
- int i, j;
-
- for ( i=0; i<win->rows; ++i ) {
- for ( j=0; j<win->cols; ++j ) {
- if ( ((win->videomem[i][j]>>8)&SELECTED) == SELECTED )
- win->videomem[i][j] &= ~(SELECTED<<8);
- }
- }
- }
-
- /* This function erases a specified section of video memory */
- void erase_video(win, x1, x2, y1, y2)
- window *win;
- int x1, x2;
- int y1, y2;
- {
- int i, j;
-
- for ( i=(x1-1); i<x2; ++i ) {
- for ( j=(y1-1); j<y2; ++j )
- win->videomem[i][j] = 0;
- }
- return;
- }
-
- /* This function "scrolls" video memory forward */
- void scroll_video(win, numlines)
- window *win;
- int numlines;
- {
- int i, n, *tmp;
-
- /* Don't scroll memory if cursor is outside of scroll region */
- if ( win->cursor.x > win->scr_lower )
- return;
-
- /* Otherwise, scroll away! */
- for ( i=0; i<numlines; ++i ) {
- /* Clear out the line that has been scrolled off the edge */
- tmp=win->videomem[win->scr_upper-1];
- for ( n=0; n<win->cols; ++n )
- tmp[n]=0;
-
- /* Now perform the scroll */
- for ( n=(win->scr_upper-1); n<(win->scr_lower-1); ++n )
- win->videomem[n]=win->videomem[n+1];
- win->videomem[n]=tmp;
- }
- /* That's it! */
- return;
- }
-
- /* This function "scrolls" video memory backward */
- void revscroll_video(win, numlines)
- window *win;
- int numlines;
- {
- int i, n, *tmp;
-
- /* Don't scroll memory if cursor is outside of scroll region */
- if ( win->cursor.x < win->scr_upper )
- return;
-
- /* Otherwise, scroll away! */
- for ( i=0; i<numlines; ++i ) {
- /* Clear out the line that has been scrolled off the edge */
- tmp=win->videomem[win->scr_lower-1];
- for ( n=0; n<win->cols; ++n )
- tmp[n]=0;
-
- /* Now perform the scroll */
- for ( n=(win->scr_lower-1); n>(win->scr_upper-1); --n )
- win->videomem[n]=win->videomem[n-1];
- win->videomem[n]=tmp;
- }
- /* That's it! */
- return;
- }
-
- /* This function inserts nulls in a line, shifting everything right */
- void rshift_video(win, numcols)
- window *win;
- int numcols;
- {
- int i;
-
- for ( i=(win->cols-1); i > (win->cursor.y-1); --i ) {
- if ( (i-numcols) >= 0 )
- win->videomem[win->cursor.x-1][i] =
- win->videomem[win->cursor.x-1][i-numcols];
- else
- win->videomem[win->cursor.x-1][i] = 0;
- }
- }
-
- int check_attr(pixel, lastattr, currattr)
- int pixel;
- int lastattr;
- unsigned char *currattr;
- {
- unsigned char change;
- unsigned char selected, reversed;
- unsigned char ohighlight, highlight;
-
- /* Thanks to Dan Dorough for the XOR code */
- change = ((lastattr ^ pixel)>>8);
- if ( change ) {
- if ( change&SELECTED ) {
- if ( change&REVERSE ) {
- if ( (*currattr)&REVERSE )
- *currattr &= ~REVERSE;
- else
- *currattr |= REVERSE;
- }
- if ( (*currattr)&SELECTED )
- *currattr &= ~SELECTED;
- else
- *currattr |= SELECTED;
- selected = ( (lastattr&SELECTED) ? 1 : 0 );
- reversed = ( (lastattr&REVERSE) ? 1 : 0 );
- ohighlight = ( selected ^ reversed );
- selected = ( ((*currattr)&SELECTED) ? 1 : 0 );
- reversed = ( ((*currattr)&REVERSE) ? 1 : 0 );
- highlight = ( selected ^ reversed );
- if ( ohighlight != highlight )
- vt_reverse(highlight);
- }
- else if ( change&REVERSE ) {
- if ( (*currattr)&REVERSE ) {
- vt_reverse(0);
- *currattr &= ~REVERSE;
- } else {
- vt_reverse(1);
- *currattr |= REVERSE;
- }
- }
- if ( change&BOLD ) {
- if ( (*currattr)&BOLD ) {
- vt_bold(0);
- *currattr &= ~BOLD;
- } else {
- vt_bold(1);
- *currattr |= BOLD;
- }
- }
- if ( change&UNDERLINE ) {
- if ( (*currattr)&UNDERLINE ) {
- vt_underline(0);
- *currattr &= ~UNDERLINE;
- } else {
- vt_underline(1);
- *currattr |= UNDERLINE;
- }
- }
- if ( change&BLINK ) {
- if ( (*currattr)&BLINK ) {
- vt_blink(0);
- *currattr &= ~BLINK;
- } else {
- vt_blink(1);
- *currattr |= BLINK;
- }
- }
- }
- return(pixel);
- }
-
- void paint_video(win)
- window *win;
- {
- unsigned char change, on=NORMAL;
- int i, j, oldattr=0;
-
- vt_setscroll(0,0);
- vt_resetattr();
- vt_goto(1+win->row_offset, 1);
- for ( i=0; i<win->rows; ++i ) {
- for ( j=0; j<win->cols; ++j ) {
- if ( win->videomem[i][j]&0xFF ) {
- oldattr=check_attr(win->videomem[i][j],
- oldattr, &on);
- printf("%c", (win->videomem[i][j]&0xFF));
- } else {
- oldattr=0;
- if ( on != NORMAL ) {
- vt_resetattr();
- on=NORMAL;
- }
- printf(" ");
- }
- }
- printf("\r");
- vt_down(1); /* This shouldn't cause scroll */
- }
- vt_setscroll(win->scr_upper+win->row_offset,
- win->scr_lower+win->row_offset);
- vt_goto(win->cursor.x+win->row_offset, win->cursor.y);
- vt_update();
- }
-